/*
	This file is part of AVRCppLib.

    AVRCppLib is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    AVRCppLib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with AVRCppLib.  If not, see <http://www.gnu.org/licenses/>.

    Copyright (C) Maxime Lemonnier 2007-2011
 */

#ifndef USARTHardwareCompatibility_H_
#define USARTHardwareCompatibility_H_

#include "USARTInterfaceCompatibility.h"
#include "../USARTHardware.h"
#include "../../../CallbackServers/FastCallbackServer.h"

namespace Coms
{

namespace USART
{


#define USARTHardware_CREATE(number) \
	new USARTHardware(USART##number##_RX_vect_number, USART##number##_UDRE_vect_number, USART##number##_TX_vect_number, &UDR##number, &UBRR##number##H, &UBRR##number##L, &UCSR##number##A, &UCSR##number##B, &UCSR##number##C)

#define USARTHardware_CASE(number)\
	case number:		static USARTHardware * usart##number = NULL;\
						if(isNull(usart##number))\
							usart##number = USARTHardware_CREATE(number);\
						instance = usart##number;\
						break

#define USART_ISR(number)\
ISR(USART##number##_RX_vect)\
{\
	FastCallbackServer::getInstance()->dispatch(USART##number##_RX_vect_number);\
}\
ISR(USART##number##_UDRE_vect)\
{\
	FastCallbackServer::getInstance()->dispatch(USART##number##_UDRE_vect_number);\
}\
ISR(USART##number##_TX_vect)\
{\
	FastCallbackServer::getInstance()->dispatch(USART##number##_TX_vect_number);\
}

#ifdef USART0
	USART_ISR(0);
#endif
#ifdef USART1
	USART_ISR(1);
#endif
#ifdef USART2
	USART_ISR(2);
#endif
#ifdef USART3
	USART_ISR(3);
#endif

USARTHardware* USARTHardware::getUSARTHardware(size_t number)
{
	static USARTHardware* instance = NULL;

	switch(number)
	{
#ifdef USART0
				USARTHardware_CASE(0);
#endif
#ifdef USART1
				USARTHardware_CASE(1);
#endif
#ifdef USART2
				USARTHardware_CASE(2);
#endif
#ifdef USART3
				USARTHardware_CASE(3);
#endif

	default:	instance = NULL;
	}

	return instance;
}

}

}

#endif /* USARTHardwareCompatibility_H_ */
